using System.Data;
using System.Collections;
using Microsoft.VisualBasic;
using System.Diagnostics;
using System;
using Microsoft.ReportingServices.ReportRendering;

namespace CustomExcelRenderCS
{
	internal class TableRenderer
	{
		
		private int g_levelRow = 0;
		private int g_levelCol = 0;
        internal static int curCellRow = 0;
        internal static int curCellCol = 0;
        internal int totCol = 0;
        internal static int totRows = 0;
        internal static double startPos;                                     // start position to precess table
        internal static double curTablePos = 0;                              // current table top position
        internal static double curTableHieght = 0;                           // set current table height in order to reset start position for tables after it
        internal static double headerPos = 0;
        internal static Hashtable columnNames = new Hashtable();            // table column name collection 
        internal static Hashtable hDataElements = new Hashtable();          // report DataElement names 
        private double reportGridLength = 0.125;
        private static double mStartRow;
        private static double mEndRow;
        internal static bool isStartRowReset;
        internal static double mSubreportStartRow;
        internal static double subReportOffset;
        internal static bool isRenderStartUp;
        internal static bool isInitSubreportStartRow;
        /// <summary>
        /// construct
        /// </summary>
		internal TableRenderer()
		{
            startPos = 0;
            startRow = 0;
            EndRow = 0;
            isStartRowReset = false;

            if (!isRenderStartUp)
            {
                subreportStartRow = 0;
                subReportOffset = 0;
                isRenderStartUp = true;
                
            }
		}

        internal static double startRow
        {
            get
            {
                return mStartRow;
            }
            set
            {
                mStartRow = value;
            }
        }

        internal static double EndRow
        {
            get
            {
                return mEndRow;
            }
            set
            {
                mEndRow = value;
            }
        }

        internal static double subreportStartRow
        {

            get
            {
                return mSubreportStartRow;
            }
            set
            {
                mSubreportStartRow = value;
            }
        }



		protected internal string Render(Microsoft.ReportingServices.ReportRendering.Table reportTable)
		{
            // allocate space for report header
            headerPos = Renderer.pageHeaderHeight / reportGridLength;
            headerPos = Math.Ceiling(headerPos / 2);

            // current table height 
            curTableHieght = ((ReportItem)reportTable).Height.ToInches();
            curTableHieght = Math.Ceiling(curTableHieght);

            if (isStartRowReset == false)
            {
                startRow = headerPos + startPos + 3;
                TextBoxFormulaHandler.startRow = startRow;
                EndRow = startRow;
            }

            if (curTableHieght > 1)
            {
                startPos = ((ReportItem)reportTable).Top.ToInches() / reportGridLength;
                startPos = Math.Ceiling(startPos / 2);
            }

            string[] rContent=new string[1]             // row content
                    , gContent = null          // table group content
                    , hContent=new string[1]            // header content
                    , fContent=new string[1];           // footer content

            // process column headers
            if (reportTable.TableHeader != null)
            {
                hContent = new string[reportTable.TableHeader.Count]; 
                this.RenderTableHeaderMembersCollection(hContent, reportTable.TableHeader);
                if (reportTable.DetailRows == null)
                {
                    startPos++;
                }

                EndRow += reportTable.TableHeader.Count; 
                 
            }

            // process table boby detailed rows
            if (reportTable.DetailRows != null)
            {                    
                totRows = reportTable.DetailRows.Count;
                totCol = reportTable.Columns.Count;
                rContent = new string[totRows];       //reportTable.DetailRows.Count

                TextBoxFormulaHandler.endRow = startRow + totRows -1;

                if (Renderer.isInSubreportContext)
                {
                    subreportStartRow += totRows + 1;
                }

                // load DataElements hashtable
                getDataElements(reportTable.DetailRows[0][0].TableCellCollection);

                // process table rows               
                this.RenderTableRowMembersCollection(rContent, reportTable.DetailRows);

                EndRow += reportTable.DetailRows.Count;
               
            }

            // process table groups rows
            if (reportTable.TableGroups != null)
            {
                // process table rows               
                this.RenderTableGroupsCollection(ref gContent, reportTable.TableGroups);
                EndRow += reportTable.TableGroups.Count;
            }

            // load table footer rows
            if (reportTable.TableFooter != null)
            {
                fContent = new string[reportTable.TableFooter.Count];
                this.RenderTableFooterCollection (fContent, reportTable.TableFooter);

                EndRow += reportTable.TableFooter.Count;
            }

            System.Text.StringBuilder pHtml = new System.Text.StringBuilder();
            StyleHandler sh = new StyleHandler(reportTable.Style);
            pHtml.AppendFormat("<TABLE BORDER=\"0\" CELLSPACING=\"0\" CELLPADDING=\"0\">");
 
            // insert rows befor start of table
            for (int i = 1; i < startPos; i++)
            {
                pHtml.Append("<tr></tr>\n");
            }

            // load table header
            foreach (string c in hContent)
            {
                if (c != null&& c != "")
                {
                    pHtml.Append("<TR>" + c + "</TR>\n");
                }

            }

            // load table detailrows
            if (reportTable.DetailRows != null)
            {
                processCollection(rContent, pHtml);
            }

            // load table groups
            if (reportTable.TableGroups != null)
            {
                processCollection(gContent, pHtml);
            }


            // load table footer
            if (reportTable.TableFooter != null)
            {
                processCollection(fContent, pHtml);
            }

			pHtml.Append("</TABLE>\n");

            Renderer.globalTrackingRow = EndRow;

			return pHtml.ToString();			
		}

        /// <summary>
        /// process table footer
        /// </summary>
        private void RenderTableFooterCollection (string [] fContent, Microsoft.ReportingServices.ReportRendering.TableHeaderFooterRows tfrow)
        {
            for (int i = 0; i < tfrow.Count; i++)
            {
                if (tfrow[i]!=null)
                {
                    TableCellCollection tcc = tfrow[i].TableCellCollection;
                    processTableCells(fContent, tcc, i);
                }
            }
        }

        /// <summary>
        /// process each row of the table
        /// </summary>
        private void RenderTableRowMembersCollection(string[] rContent, Microsoft.ReportingServices.ReportRendering.TableRowsCollection mColl )
		{
            
            for (int i = 0; i <= mColl.Count - 1; i++)
            {
                
                if (mColl[i] != null)
                {
                    // process table row
                    for (int j = 0; j < mColl[i].Count; j++)
                    {

                        // process each column on the row
                        if (mColl[i][j] != null)
                        {
                            curCellCol = j;
                            TextBoxFormulaHandler.currentCol = curCellCol;
                            TableCellCollection tcc = mColl[i][j].TableCellCollection;
                            processTableCells(rContent, tcc, i);
                        }
                    }
                }
                curCellRow ++;
            }
		}
		
              /// <summary>
        /// process each row of the table groups
        /// </summary>
        private void RenderTableGroupsCollection(ref string[] rContent, Microsoft.ReportingServices.ReportRendering.TableGroupCollection mColl)
        {
            for (int i = 0; i <= mColl.Count - 1; i++)
            {
                TableGroup tableGroup = mColl[i];

                string[] groupsHeaderContent=null,
                         groupsDetailContent=null,
                         groupsFooterContent=null;

                if (tableGroup.GroupHeader != null)
                {
                    groupsHeaderContent = new string[tableGroup.GroupHeader.Count];
                    RenderTableHeaderMembersCollection(groupsHeaderContent, tableGroup.GroupHeader);
                }
                if (tableGroup.DetailRows!=null)
                {
                    groupsDetailContent = new string[tableGroup.DetailRows.Count];
                    RenderTableRowMembersCollection(groupsDetailContent, tableGroup.DetailRows);
                }
                if (tableGroup.GroupFooter != null)
                {
                    groupsFooterContent = new string[tableGroup.GroupFooter.Count];
                    RenderTableFooterCollection(groupsFooterContent, tableGroup.GroupFooter);
                }

                string[] tempGroupContent = new string[(groupsHeaderContent==null?0:groupsHeaderContent.Length)+(groupsDetailContent==null?0:groupsDetailContent.Length)+(groupsFooterContent==null?0:groupsFooterContent.Length)];

                if (tempGroupContent.Length > 0)
                {
                    int offset = 0;
                    if (groupsHeaderContent != null)
                    {
                        groupsHeaderContent.CopyTo(tempGroupContent, offset);
                        offset = groupsHeaderContent.Length;
                    }
                    if (groupsDetailContent != null)
                    {
                        groupsDetailContent.CopyTo(tempGroupContent, offset);
                        offset += groupsDetailContent.Length;
                    }
                    if (groupsFooterContent != null)
                    {
                        groupsFooterContent.CopyTo(tempGroupContent, offset);
                    }

                    offset = 0;
                    string[] temp = new string[(rContent == null?0:rContent.Length) + tempGroupContent.Length];
                    if (rContent != null)
                    {
                        rContent.CopyTo(temp, offset);
                        offset = rContent.Length;
                    }

                    tempGroupContent.CopyTo(temp, offset);
                    rContent = temp;
                }
            }
            
        }

        /// <summary>
        /// process table header rows
        /// </summary>
		private void RenderTableHeaderMembersCollection(string [] cContent,  Microsoft.ReportingServices.ReportRendering.TableHeaderFooterRows mColl )
		{
            StyleHandler sh = null;

            for (int i = 0; i <= mColl.Count - 1; i++)
            {
                if (mColl[i] != null)
                {
                    TableCellCollection tcc = mColl[i].TableCellCollection;
                    processTableCells(cContent, tcc, i);
                }
            }
            
		}

        /// <summary>
        /// process each cell of the table
        /// </summary>
        private void processTableCells(string [] sContent, TableCellCollection tcc, int i)
        {
            StyleHandler sh = null;

            for (int k = 0; k < tcc.Count; k++)
            {
                sh = new StyleHandler(tcc[k].ReportItem.Style);
                //if (l + k < mColl.Count)
                //{
                curCellCol = k;
                TextBoxFormulaHandler.currentCol = curCellCol;
                sContent[i] += string.Format("<TD ROWSPAN=\"{0}\" COLSPAN=\"{1}\" BGCOLOR=\"{2}\" STYLE=\"{3}\">", tcc[k].ColSpan.ToString(), tcc[k].ColSpan.ToString(), sh.GetStyleColorRGBCode("BackgroundColor"), sh.GetHtmlStyleString(typeof(Microsoft.ReportingServices.ReportRendering.Table)))
                + Renderer.RenderReportItem(tcc[k].ReportItem)
                + "</td>\n";
                //}

                // save report item for identifing which item to convert during Excel formula conversion
            
            }
        }

        /// <summary>
        /// render each row of rowcollection
        /// </summary>
        private void processCollection(string[] rContent, System.Text.StringBuilder pHtml)
        {
            for (int r = 0; r <= rContent.Length - 1; r++)
            {
                pHtml.Append("<TR>");
                pHtml.Append(rContent[r]);
                //for (int c = 0; c <= lastCol; c++)
                //{
                //    Microsoft.ReportingServices.ReportRendering.TableGroupCollection mc = reportTable.ToggleItem;
                //    sh = new StyleHandler(mc[r, c].ReportItem.Style);
                //    pHtml.Append(string.Format("<TD STYLE=\"{0}\">", sh.GetHtmlStyleString(typeof(Microsoft.ReportingServices.ReportRendering.Table))));
                //    pHtml.Append(string.Format("<FONT STYLE=\"{0}\">", sh.GetHtmlStyleString(mc[r, c].ReportItem.GetType())));
                //    if (mc[r, c].ReportItem != null)
                //    {

                //        pHtml.Append(Renderer.RenderReportItem(mc[r, c].ReportItem));

                //    }
                //    else
                //    {

                //        pHtml.Append("&nbsp;");
                //    }
                //    pHtml.Append("</FONT></TD>");
                //}

                pHtml.Append("</TR>\n");
            }		
			

        }

        /// <summary>
        /// load hashtable hDataElements from report item **
        /// </summary>
        private void getDataElements(TableCellCollection tcc)
        {
            for (int k = 0; k< tcc.Count; k++)
                hDataElements[tcc[k].ReportItem.DataElementName.ToLower()] = k;   
        }
		
	}
	
	
	
}
